package com.yxy.chatserver.service.impl;

import com.yxy.chatserver.constant.DefaultConstant;
import com.yxy.chatserver.constant.ExceptionConstant;
import com.yxy.chatserver.constant.MessageConstant;
import com.yxy.chatserver.domain.dto.UserLoginDTO;
import com.yxy.chatserver.domain.po.Friends;
import com.yxy.chatserver.domain.vo.FriendsListVO;
import com.yxy.chatserver.domain.vo.UserLoginVO;
import com.yxy.chatserver.domain.vo.UserQueryVO;
import com.yxy.chatserver.exception.*;
import com.yxy.chatserver.mapper.UserMapper;
import com.yxy.chatserver.domain.dto.UserRegisterDTO;
import com.yxy.chatserver.domain.po.User;
import com.yxy.chatserver.properties.AESProperties;
import com.yxy.chatserver.properties.JwtProperties;
import com.yxy.chatserver.service.UserService;
import com.yxy.chatserver.util.AESUtil;
import com.yxy.chatserver.util.JwtUtil;
import com.yxy.chatserver.util.SnowflakeIdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AESProperties aesProperties;
    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 注册
     *
     * @param userRegisterDTO
     */
    @Override
    public void register(UserRegisterDTO userRegisterDTO) {
        // 查询用户是否已存在
        User user = null;
        user = userMapper.selectByUsername(userRegisterDTO.getUsername());
        if (user != null) {
            throw new UserAlreadyExistsException(MessageConstant.USER_ALREADY_EXISTS);
        }
        user = userMapper.selectByEmail(userRegisterDTO.getEmail());
        if (user != null) {
            throw new EmailAlreadyRegisteredException(MessageConstant.EMAIL_ALREADY_REGISTERED);
        }
        user = new User();
        BeanUtils.copyProperties(userRegisterDTO, user);
        // 雪花算法生成id
        SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(1, 1);
        user.setId(snowflakeIdGenerator.nextId());
        user.setCreateTime(LocalDateTime.now());
        user.setNickname(DefaultConstant.DEFAULT_USER_NICKNAME);
        // 默认头像
        user.setAvatar(DefaultConstant.DEFAULT_USER_AVATAR);
        // 加密密码
        try {
            user.setPassword(AESUtil.encrypt(user.getPassword(), aesProperties.getSecretKey()));
        } catch (Exception e) {
            throw new ServerException(ExceptionConstant.SERVER_ERROR);
        }
        // 新增用户
        userMapper.insert(user);
    }

    /**
     * 登录
     *
     * @param userLoginDTO 登录信息
     */
    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        // 查询用户是否存在
        User user = userMapper.selectByUsername(userLoginDTO.getUsername());
        if (user == null) {
            throw new UserNotFoundException(MessageConstant.USER_NOT_FOUND);
        }
        // 判断密码
        try {
            String IncomingPwd = AESUtil.encrypt(userLoginDTO.getPassword(), aesProperties.getSecretKey());
            if (!IncomingPwd.equals(user.getPassword())) {
                throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
            }
        } catch (PasswordErrorException e) {
            throw e;
        } catch (Exception e) {
            throw new ServerException(ExceptionConstant.SERVER_ERROR);
        }
        // 验证通过
        UserLoginVO vo = new UserLoginVO();
        BeanUtils.copyProperties(user, vo);
        String token = new JwtUtil(jwtProperties).generateToken(user.getUsername(), user.getId());
        vo.setToken(token);
        // 将id转为字符串
        vo.setId(String.valueOf(user.getId()));
        return vo;
    }

    /**
     * 查询用户
     *
     * @param query 查询条件
     * @return
     */
    @Override
    public UserQueryVO queryUser(String query) {
        User user = userMapper.selectByusernameOrEmail(query);
        if (user == null) {
            throw new UserNotFoundException(MessageConstant.USER_NOT_FOUND);
        }
        UserQueryVO vo = new UserQueryVO();
        BeanUtils.copyProperties(user, vo);
        vo.setId(String.valueOf(user.getId()));
        return vo;
    }

    /**
     * 查询用户好友列表
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<FriendsListVO> queryFriendsList(String userId) {
        List<Friends> friendsList = userMapper.queryFriendsList(userId);
        if (friendsList.size() == 0) {
            log.warn("用户好友列表为空");
            return Collections.emptyList();
        }
        List<FriendsListVO> voList = friendsList.stream().map(friends -> {
            FriendsListVO vo = new FriendsListVO();
            BeanUtils.copyProperties(friends, vo);
            vo.setId(String.valueOf(friends.getFriendId()));
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    /**
     * 根据id查询用户
     *
     * @param fromUserId 用户id
     * @return
     */
    @Override
    public User getById(String fromUserId) {
        User user = userMapper.getById(fromUserId);
        if (user == null) {
            throw new UserNotFoundException(MessageConstant.USER_NOT_FOUND);
        }
        return user;
    }

    /**
     * 添加好友
     *
     * @param userId
     * @param friendId
     * @param nickname
     * @param avatar
     */
    @Override
    public void addFriend(String userId, String friendId, String nickname, String avatar) {
        Friends friends = new Friends();
        friends.setUserId(userId);
        friends.setFriendId(friendId);
        friends.setNickname(nickname);
        friends.setAvatar(avatar);
        friends.setCreateTime(LocalDateTime.now());
        userMapper.addFriend(friends);
    }

    /**
     * 检查是否为好友
     *
     * @param fromUserId
     * @param toUserId
     * @return
     */
    @Override
    public Boolean checkFriend(String userId, String friendId) {
        return userMapper.checkFriend(userId, friendId);
    }
}
